package cn.buk.tms.dto;

import cn.buk.tms.entity.bill.BillHotelBooking;
import cn.buk.tms.entity.bill.BillRentalCarOrder;
import cn.buk.tms.entity.bill.BillTrainTicket;
import cn.buk.tms.entity.bill.SettlementSheet;
import cn.buk.tms.common.dto.CustomerDto;
import cn.buk.tms.factory.CustomerDtoFactory;
import cn.buk.common.util.DateUtil;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.BeanUtils;

public class SettlementReportDto {

    private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";

    private String settlementNo;

    private int customerType;

    private CustomerDto customer;

    /**
     * 结算单报表模板ID（使用哪种导出模板）
     */
    private int reportTemplateId;

    private String name;

    private double amount;


    //机票
    private List<ReportTicketDto> tickets;
    //退票
    private List<ReportTicketRefundDto> refunds;
    //改签
    private List<ReportTicketChangeDto> changes;
    //服务
    private List<SettlementReportVasDto> vasOrders;
    //酒店
    private List<BillHotelBooking> hotels;
    //火车票
    private List<BillTrainTicket> trains;
    //用车
    private List<BillRentalCarOrder> carOrders;

    public static SettlementReportDto createBySettlement(SettlementSheet ss) {
        SettlementReportDto dto = new SettlementReportDto();
        BeanUtils.copyProperties(ss, dto);

        if (ss.getCustomer() != null) {
            CustomerDto customerDto = CustomerDtoFactory.createByCustomer(ss.getCustomer());
            dto.setCustomer(customerDto);
        }

        return dto;
    }

    public static StringBuilder exportTitle0() {
        StringBuilder sb = new StringBuilder();
        sb.append("结算单号,");
        sb.append("结算单名称,");
        sb.append("客户名称,");
        sb.append("客户编号,");
        sb.append("金额,");
        sb.append("\r");

        return sb;
    }

    public static StringBuilder exportContent0(SettlementReportDto dto) {
        StringBuilder sb = new StringBuilder();
        sb.append(dto.getSettlementNo()).append(",");
        sb.append(dto.getName()).append(",");
        if (dto.getCustomer() != null) {
            sb.append(dto.getCustomer().getName()).append(",");
            sb.append(dto.getCustomer().getCustomerCode()).append(",");
        } else {
            sb.append(",");
            sb.append(",");
        }
        sb.append(dto.getAmount()).append(",");
        sb.append("\r");

        return sb;
    }

    public static StringBuilder exportTitle1() {
        StringBuilder sb = new StringBuilder();
        sb.append("订单日期,");
        sb.append("乘机人,");
        sb.append("出发,");
        sb.append("到达,");
        sb.append("航班号,");
        sb.append("起飞日期,");
        sb.append("起飞时间,");
        sb.append("销售价,");
        sb.append("税收,");
        sb.append("应付,");
        sb.append("票号,");
        sb.append("备注,");
        sb.append("\r");

        return sb;
    }

    public static StringBuilder exportContent1(SettlementReportDto dto) {
        StringBuilder sb = exportTickets(dto.getTickets());

        StringBuilder sb1 = exportRefunds(dto.getRefunds());
        sb.append(sb1);

        sb1 = exportChanges(dto.getChanges());
        sb.append(sb1);

        sb1 = exportVasOrders(dto.getVasOrders());
        sb.append(sb1);

        sb1 = exportHotels(dto.getHotels());
        sb.append(sb1);

        sb1 = exportTrains(dto.getTrains());
        sb.append(sb1);

        return sb;
    }

    private static StringBuilder exportTrains(List<BillTrainTicket> trains) {
        StringBuilder sb = new StringBuilder();

        for(BillTrainTicket t: trains) {
            if (t.getSaleDate() != null) {
              sb.append(DateUtil.formatDate(t.getSaleDate(), DEFAULT_DATE_FORMAT)).append(",");
            } else {
              sb.append(",");
            }

            if (t.getPassengerName() != null) {
              sb.append(t.getPassengerName().replace(",", "、"));
            }
            sb.append(",");

            sb.append(t.getDcity()).append(",");
            sb.append(t.getAcity()).append(",");
            sb.append(t.getTrainNo()).append(",");
            sb.append(DateUtil.formatDate(t.getDdate(), DEFAULT_DATE_FORMAT)).append(",");
            sb.append(",");

            sb.append(t.getTotal()).append(",");
            sb.append(",");

            sb.append(t.getTotal()).append(",");

            sb.append(",");
            sb.append("火车票").append(",");

            sb.append("\r");
        }
        return sb;
    }

    private static StringBuilder exportHotels(List<BillHotelBooking> hotels) {
        StringBuilder sb = new StringBuilder();

        for(BillHotelBooking t: hotels) {
            if (t.getSaleDate() != null) {
              sb.append(DateUtil.formatDate(t.getSaleDate(), DEFAULT_DATE_FORMAT));
            }
            sb.append(",");

            String temp = t.getPassengerName() == null ? "" : t.getPassengerName();
            temp = temp.replace(",", ";");
            sb.append(temp).append(",");

            sb.append(",");
            sb.append(",");
            sb.append(t.getHotelName().replace(",", " ")).append(",");
            sb.append(DateUtil.formatDate(t.getDdate(), DEFAULT_DATE_FORMAT)).append(",");
            sb.append(DateUtil.formatDate(t.getLeaveDate(), DEFAULT_DATE_FORMAT)).append(",");

            sb.append(t.getTotalAmount()).append(",");
            sb.append(",");

            sb.append(t.getTotalAmount()).append(",");

            sb.append(",");
            sb.append("酒店").append(",");

            sb.append("\r");
        }
        return sb;
    }

    private static StringBuilder exportVasOrders(List<SettlementReportVasDto> vasOrders) {
        StringBuilder sb = new StringBuilder();

        for(SettlementReportVasDto ticket: vasOrders) {
            sb.append(DateUtil.formatDate(ticket.getOrderDate(), DEFAULT_DATE_FORMAT)).append(",");

            String temp = ticket.getPassengerName() == null ? "" : ticket.getPassengerName();
            sb.append(temp).append(",");

            if (!ticket.getDetails().isEmpty()) {
                appendFlightInfo(sb, ticket.getDetails().get(0));
            } else {
                sb.append(",");
                sb.append(",");
                sb.append(",");
                sb.append(",");
                sb.append(",");
            }

            sb.append(ticket.getTotal()).append(",");
            sb.append(",");

            sb.append(ticket.getTotal()).append(",");

            sb.append(",");
            sb.append(ticket.getProductName()).append(",");

            sb.append("\r");

            if (ticket.getDetails().size() > 1) {
                sb.append(exportMoreFlight(ticket.getDetails()));
            }
        }
        return sb;
    }

    private static StringBuilder exportChanges(List<ReportTicketChangeDto> changes) {
        StringBuilder sb = new StringBuilder();

        for(ReportTicketChangeDto ticket: changes) {
            sb.append(DateUtil.formatDate(ticket.getOrderDate(), DEFAULT_DATE_FORMAT)).append(",");
            sb.append(ticket.getPassengerName()).append(",");

            if (!ticket.getDetails().isEmpty()) {
                appendFlightInfo(sb, ticket.getDetails().get(0));
            } else {
                sb.append(",").append(",").append(",").append(",").append(",");
            }

            sb.append(",");
            sb.append(",");

            sb.append(ticket.getAmount()).append(",");

            sb.append(ticket.getShowTicketNo()).append(",");
            sb.append("改签");

            sb.append("\r");

            if (ticket.getDetails().size() > 1) {
                sb.append(exportMoreFlight(ticket.getDetails()));
            }
        }
        return sb;
    }

    private static StringBuilder exportRefunds(List<ReportTicketRefundDto> refunds) {
        StringBuilder sb = new StringBuilder();

        for(ReportTicketRefundDto ticket: refunds) {
            sb.append(DateUtil.formatDate(ticket.getOrderDate(), DEFAULT_DATE_FORMAT)).append(",");
            sb.append(ticket.getPassengerName()).append(",");

            if (ticket.getDetails().isEmpty()) {
                sb.append(",");
                sb.append(",");
                sb.append(",");
                sb.append(",");
                sb.append(",");
            } else {
                ReportTicketDetailDto flt0 = ticket.getDetails().get(0);
                appendFlightInfo(sb, flt0);
            }

            sb.append(",");
            sb.append(",");

            sb.append(ticket.getAmount()).append(",");

            sb.append(ticket.getShowTicketNo()).append(",");
            sb.append("退票,");

            sb.append("\r");

            if (ticket.getDetails().size() > 1) {
                sb.append(exportMoreFlight(ticket.getDetails()));
            }
        }

        return sb;
    }

    private static StringBuilder exportTickets(List<ReportTicketDto> tickets) {
        StringBuilder sb = new StringBuilder();

        for(ReportTicketDto ticket: tickets) {
            sb.append(DateUtil.formatDate(ticket.getOrderDate(), DEFAULT_DATE_FORMAT)).append(",");
            sb.append(ticket.getPassengerName()).append(",");

            if (ticket.getDetails().isEmpty()) {
                sb.append(",");
                sb.append(",");
                sb.append(",");
                sb.append(",");
                sb.append(",");
            } else {
                appendFlightInfo(sb, ticket.getDetails().get(0));
            }

            sb.append(ticket.getShowParvalue()).append(",");
            sb.append(ticket.getTax()).append(",");

            sb.append(ticket.getAmount()).append(",");

            sb.append(ticket.getShowTicketNo()).append(",");
            if (ticket.getTicketType() == 1) {
                sb.append("退票");
            } else if (ticket.getTicketType() == 2) {
                sb.append("改签");
            }
            sb.append(",");
            sb.append("\r");

            if (ticket.getDetails().size() > 1) {
                sb.append(exportMoreFlight(ticket.getDetails()));
            }
        }

        return sb;
    }

    private static void appendFlightInfo(StringBuilder sb, ReportTicketDetailDto flt0) {
        sb.append(flt0.getDportName()).append(",");
        sb.append(flt0.getAportName()).append(",");
        sb.append(flt0.getFlight()).append(",");
        sb.append(flt0.getDdate()).append(",");
        sb.append(flt0.getDtime()).append(",");
    }

    private static StringBuilder exportMoreFlight(List<ReportTicketDetailDto> details) {
        StringBuilder sb = new StringBuilder();

        int index = 0;
        for (ReportTicketDetailDto flt : details){
            index++;
            if (index == 1) {
              continue;
            }
            sb.append(",");
            sb.append(",");

            appendFlightInfo(sb, flt);

            sb.append(",");
            sb.append(",");
            sb.append(",");
            sb.append(",");
            sb.append(",");
            sb.append(",");
            sb.append(",");
            sb.append(",");

            sb.append("\r");
        }

        return sb;
    }

    public List<ReportTicketDto> getTickets() {
        return tickets;
    }

    public void setTickets(List<ReportTicketDto> tickets) {
        this.tickets = tickets;
    }

    public List<ReportTicketRefundDto> getRefunds() {
        return refunds;
    }

    public void setRefunds(List<ReportTicketRefundDto> refunds) {
        this.refunds = refunds;
    }

    public List<SettlementReportVasDto> getVasOrders() {
        return vasOrders;
    }

    public void setVasOrders(List<SettlementReportVasDto> vasOrders) {
        this.vasOrders = vasOrders;
    }

    public List<BillHotelBooking> getHotels() {
        return hotels;
    }

    public void setHotels(List<BillHotelBooking> hotels) {
        this.hotels = hotels;
    }

    public List<BillTrainTicket> getTrains() {
        return trains;
    }

    public void setTrains(List<BillTrainTicket> trains) {
        this.trains = trains;
    }

    public String getSettlementNo() {
        return settlementNo;
    }

    public void setSettlementNo(String settlementNo) {
        this.settlementNo = settlementNo;
    }

    public int getCustomerType() {
        return customerType;
    }

    public void setCustomerType(int customerType) {
        this.customerType = customerType;
    }

    public CustomerDto getCustomer() {
        return customer;
    }

    public void setCustomer(CustomerDto customer) {
        this.customer = customer;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getAmount() {
        return amount;
    }

    public void setAmount(double amount) {
        this.amount = amount;
    }

    public List<ReportTicketChangeDto> getChanges() {
        return changes;
    }

    public void setChanges(List<ReportTicketChangeDto> changes) {
        this.changes = changes;
    }

    public int getReportTemplateId() {
        return reportTemplateId;
    }

    public void setReportTemplateId(int reportTemplateId) {
        this.reportTemplateId = reportTemplateId;
    }

    public List<BillRentalCarOrder> getCarOrders() {
        if (carOrders == null) {
            carOrders = new ArrayList<>();
        }
        return carOrders;
    }

    public void setCarOrders(List<BillRentalCarOrder> carOrders) {
        this.carOrders = carOrders;
    }
}
